package com.news.yp.baselibrary.findbyid;

import android.app.Activity;
import android.view.View;

import com.news.yp.baselibrary.annotation.ViewById;
import com.news.yp.baselibrary.annotation.ViewClick;

import java.lang.reflect.Field;
import java.lang.reflect.Method;


/**
 * IOC注解框架
 */
public class ViewUtils {

    private ViewUtils() {
    }

    //前期在activity里面使用
    public static void init(Activity activity) {
        pareInject(new ViewFind(activity), activity);
    }

    //后期
    public static void init(View view) {
        pareInject(new ViewFind(view), view);
    }

    //后期 Fragment
    public static void init(View view, Object root) {
        pareInject(new ViewFind(view), root);
    }

    private static void pareInject(ViewFind finder, Object object) {
        injectFields(finder, object);
        injectMethods(finder, object);
    }

    /**
     * 方法注入
     *
     * @param finder
     * @param object
     */
    private static void injectMethods(ViewFind finder, Object object) {
        Class<?> clazz = object.getClass();
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            //否则私有方法无法访问
            method.setAccessible(true);
            ViewClick annotation = method.getAnnotation(ViewClick.class);
            if (annotation != null) {
                int[] value = annotation.value();
                for (int i : value) {

                    View viewById = finder.findViewById(i);

                    viewById.setOnClickListener(new MyDecareOnClickListener(method, object));
                }
            }
        }
    }

    /**
     * 属性注入
     *
     * @param finder
     * @param object
     */
    private static void injectFields(ViewFind finder, Object object) {
        Class<?> clazz = object.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //否则私有无法访问
            field.setAccessible(true);
            ViewById annotation = field.getAnnotation(ViewById.class);
            if (annotation != null) {
                int value = annotation.value();
                View view = finder.findViewById(value);
                try {
                    field.set(object, view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static class MyDecareOnClickListener implements View.OnClickListener {
        private Method mMethod;
        private Object mObject;

        public MyDecareOnClickListener(Method method, Object object) {
            this.mObject = object;
            this.mMethod = method;
        }

        @Override
        public void onClick(View view) {
            try {
                mMethod.invoke(mObject);
            } catch (Exception e) {
                try {
                    mMethod.invoke(mObject, view);
                } catch (Exception e1) {

                }
            }
        }
    }
}

